package com.cskaoyan.shopping.service.impl;


import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.constant.ShoppingRetCode;
import com.cskaoyan.mall.dto.ClearCartItemRequest;
import com.cskaoyan.mall.dto.ClearCartItemResponse;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.*;
import com.cskaoyan.shopping.service.ICartService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static java.util.Comparator.comparing;


/**
 * 有关购物车的实现类
 *
 * @author : Caspar
 * @since : 2022.07.09 09:32
 */
@Slf4j
@Service
public class ICartServiceImpl implements ICartService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ItemMapper itemMapper;

    /**
     * 获得购物车的列表
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.CartListByIdResponse
     * @author: Caspar CXC
     * @since 2022/07/09 9:33
     */
    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        CartListByIdResponse response = new CartListByIdResponse();

        try {
            request.requestCheck();
            String uid = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> cartMap = redissonClient.getMap(uid);

            List<CartProductDto> cartProductDtos = new ArrayList<>();

            // 循环遍历取出购物车里的商品
            Iterator<Map.Entry<Long, CartProductDto>> iterator = cartMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Long, CartProductDto> entry = iterator.next();
                CartProductDto cartProductDto = entry.getValue();
                cartProductDtos.add(cartProductDto);
            }

            // 对购物车里的商品按照添加时间进行排序
            cartProductDtos.sort(comparing(CartProductDto::getAddTime).reversed());

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            response.setCartProductDtos(cartProductDtos);
        } catch (Exception e) {
            log.error("ICartServiceImpl.getCartListById Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    /**
     * 增加商品到购物车
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.AddCartResponse
     * @author: Caspar CXC
     * @since 2022/07/09 11:15
     */
    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse response = new AddCartResponse();

        try {
            request.requestCheck();
            String uid = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> cartMap = redissonClient.getMap(uid);

            /*
            增加商品到购物车：
            1、确定用户的id
            2、确定商品的id，需要存进去productId，传进来并封装进AddCartRequest里面的是productId
            3、确定商品的数量，需要存进去productNum，传进来并封装进AddCartRequest里面的是productNum
            4、根据商品的id，需要取出salePrice、limitNum、checked、productName、productImg
            5、productId、salePrice、productNum、limitNum、checked、productName、productImg封装成cartProductDto存进redis
             */

            Long productId = request.getProductId();
            Integer num = request.getProductNum();

            // 去商品表中查询基本信息
            Item item = itemMapper.selectByPrimaryKey(productId);
            item.setNum(num);

            // 调用com.cskaoyan.shopping.converter.CartItemConverter类下的静态方法
            // 这是老师定义的类，没写成接口
            CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
            cartProductDto.setChecked("false");
            cartProductDto.setAddTime(new Date());
            cartMap.put(productId, cartProductDto);

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartServiceImpl.addToCart Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    /**
     * 更新购物车里的内容
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.UpdateCartNumResponse
     * @author: Caspar CXC
     * @since 2022/07/09 14:28
     */
    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();

        try {
            request.requestCheck();
            Long userId = request.getUserId();
            String uid = String.valueOf(userId);
            Map<Long, CartProductDto> cartMap = redissonClient.getMap(uid);

            Iterator<Map.Entry<Long, CartProductDto>> iterator = cartMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Long, CartProductDto> entry = iterator.next();
                Long productId = entry.getKey();

                if (productId.equals(request.getProductId())) {
                    CartProductDto cartProductDto = entry.getValue();
                    Long productNum = Long.valueOf(request.getProductNum());
                    cartProductDto.setProductNum(productNum);

                    if (request.getChecked().equals("true")) {
                        cartProductDto.setChecked("true");
                    } else if (request.getChecked().equals("false")) {
                        cartProductDto.setChecked("false");
                    }

                    cartMap.put(productId, cartProductDto);
                }

            }
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartServiceImpl.updateCartNum Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    /**
     * 全选或全取消购物车中的商品
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.CheckAllItemResponse
     * @author Yan Dexuan
     * @since 2022/07/10 16:57
     */
    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {

        CheckAllItemResponse response = new CheckAllItemResponse();

        try {
            request.requestCheck();
            String userId = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> map = redissonClient.getMap(userId);
            Iterator<Map.Entry<Long, CartProductDto>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Long, CartProductDto> next = iterator.next();
                Long productId = next.getKey();
                CartProductDto productDto = next.getValue();
                productDto.setChecked(request.getChecked());

                //将状态更改后的对象传入Map。
                map.put(productId, productDto);

            }

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {

            log.error("ICartServiceImpl.checkAllCartItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);

        }

        return response;
    }

    /**
     * 删除购物车中的商品
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.DeleteCartItemResponse
     * @author Yan Dexuan
     * @since 2022/07/10 16:55
     */
    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {

        DeleteCartItemResponse response = new DeleteCartItemResponse();

        try {
            request.requestCheck();
            String userId = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> map = redissonClient.getMap(userId);

            Iterator<Map.Entry<Long, CartProductDto>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Long, CartProductDto> next = iterator.next();
                Long productId = next.getKey();
                //CartProductDto productDto = next.getValue();
                if (productId.equals(request.getItemId())) {
                    map.remove(productId);
                }
            }

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICartServiceImpl.deleteCartItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    /**
     * 删除购物车中选中的商品
     *
     * @param request
     * @return com.cskaoyan.shopping.dto.DeleteCheckedItemResposne
     * @author Yan Dexuan
     * @since 2022/07/10 16:55
     */
    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {

        DeleteCheckedItemResposne resposne = new DeleteCheckedItemResposne();

        try {
            request.requestCheck();
            String userId = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> map = redissonClient.getMap(userId);

            //取出CartProductDto对象。
            Iterator<Map.Entry<Long, CartProductDto>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Long, CartProductDto> next = iterator.next();
                Long productId = next.getKey();
                CartProductDto productDto = next.getValue();
                if ("true".equals(productDto.getChecked())) {
                    map.remove(productId);
                }
            }

            resposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            resposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICartServiceImpl.deleteCheckedItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(resposne, e);
        }

        return resposne;
    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        ClearCartItemResponse clearCartItemResponse = new ClearCartItemResponse();

        try {
            request.requestCheck();
            String userId = String.valueOf(request.getUserId());
            Map<Long, CartProductDto> map = redissonClient.getMap(userId);
            List<Long> productIds = request.getProductIds();
            for (Long productId : productIds) {
                map.remove(productId);
            }

            clearCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            clearCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICartServiceImpl.clearCartItemByUserID Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(clearCartItemResponse, e);
        }
        return clearCartItemResponse;
    }
}
